'use strict';

const BaseService = require('./base');
const { OrderStatusEnum, OrderPaymentEnum} = require('../utils/enum');
const dayjs = require('dayjs');
const { Op } = require('sequelize');
/**
 * 生成订单号
 * @return {string}
 */
function generateOrderNo() {
    const now = dayjs();
    // 生成格式：年月日时分秒+4位随机数
    return 'ON' + now.format('YYYYMMDDHHmmss') + Math.floor(Math.random() * 10000).toString().padStart(4, '0');
}

class OrderService extends BaseService {
    constructor(ctx) {
        super(ctx, 'Order');
    }
    pageOrder() {
        return [
            ['id', 'desc']
        ]
    }
    listOrder() {
        return [
            ['id', 'desc']
        ]
    }
    getPageInclude() {
        return [
            {
                model: this.ctx.model.User,
                as: 'user',
            },
            {
                model: this.ctx.model.OrderItem,
                as: 'items'
            },
            {
                model: this.ctx.model.Comment,
                as: 'comments'
            }
        ]
    }
    getOneInclude() {
        return [
            {
                model: this.ctx.model.OrderItem,
                as: 'items'
            },

            {
                model: this.ctx.model.Comment,
                as: 'comments'
            }
        ]
    }

    /**
     * 创建订单
     * @param {Object} orderData - 订单数据
     * @return {Promise<*>}
     */
    async create(orderData) {
        const { ctx } = this;
        /**
         * 校验用户
         */
        if (!orderData.user_id) throw new Error('用户不存在');
        // 检查用户是否存在
        const user = await ctx.model.User.findOne({
            where: {
                id: orderData.user_id
            }
        })
        if (!user) {
            throw new Error('用户不存在');
        }
        if (!user.status) {
            throw new Error('用户已禁用');
        }
        /**
         * 校验产品
         */
        // 检查产品是否存在
        const product = await ctx.model.Product.findAll({
            where: {
                id: {
                    [Op.in]: orderData.cartList.map(item => item.product_id),
                },
                status: 1
            }
        })
        if (!product || !product.length) throw new Error('产品不存在');
        if (product.length !== orderData.cartList.length) throw new Error('有下架产品');
        // 创建订单
        try {
            // 订单事务
            const transaction = await ctx.model.transaction();
            // 1. 生成订单号
            const orderNo = generateOrderNo();
            // 2. 创建主订单
            const createData = {
                order_no: orderNo,
                ...orderData,
                // 产品快照
                product_detail: JSON.stringify(orderData.cartList)
            }
            // 3. 扣减产品库存
            for (let i = 0; i < orderData.cartList.length; i++) {
                const cartItem = orderData.cartList[i];
                const _product = await this.ctx.model.Product.findOne({ where: { id: cartItem.product_id } });
                if (_product) {
                    // 使用 decrement 方法减少库存
                    await _product.decrement('stock', { by: cartItem.count, transaction });
                }
            }
            // 4. 创建子订单
            const order = await ctx.model.Order.create(createData, { transaction });
            // 5. 批量创建子订单
            await ctx.model.OrderItem.bulkCreate(orderData.cartList.map(item => {
                return {
                    order_id: order.id,
                    order_no: orderNo,
                    user_id: orderData.user_id,
                    product_id: item.product_id,
                    count: item.count,
                    product_detail: JSON.stringify(item),
                }
            }), { transaction });
            // 6. 删除购物车
            await ctx.model.Cart.destroy({
                where: {
                    user_id: orderData.user_id,
                    id: {
                        [Op.in]: orderData.cartList.map(item => item.id)
                    }
                },
                transaction
            });
            await transaction.commit();
            // 6. 返回订单信息
            return order.id
        } catch (error) {
            await transaction.rollback();
            throw error;
        }
    }

    /**
     * 取消订单
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async cancel(params) {
        const { ctx } = this;
        const { id } = params;
        const transaction = await ctx.model.transaction();

        try {
            // 1. 查询订单
            const order = await this.ctx.model.Order.findOne({
                where: {
                    id,
                },
            });

            if (!order) {
                throw new Error('订单不存在');
            }

            // 2. 判断订单状态
            if (order.status !== OrderStatusEnum.PENDING_PAYMENT) {
                throw new Error('只有待支付的订单才能取消');
            }

            // 3. 更新订单状态
            await order.update({
                status: OrderStatusEnum.CANCELLED,
                cancel_time: new Date(),
            }, { transaction });

            await transaction.commit();
            return true;
        } catch (error) {
            await transaction.rollback();
            throw error;
        }
    }
    /**
     * 获取订单详情
     * @param {Object} params - 参数
     * @return {Promise<Object>}
     */
    async detail(params) {
        const { ctx } = this;
        const { id } = params;

        // 查询订单
        const order = await this.model.findOne({
            where: { id },
            include: [
                {
                    model: ctx.model.Product,
                    as: 'product',
                    attributes: ['id', 'title', 'post_url', 'price']
                }
            ]
        });

        if (!order) {
            throw new Error('订单不存在');
        }

        // 格式化时间
        const result = order.toJSON();
        if (result.create_time) {
            result.create_time = dayjs(result.create_time).format('YYYY-MM-DD HH:mm:ss');
        }
        if (result.pay_time) {
            result.pay_time = dayjs(result.pay_time).format('YYYY-MM-DD HH:mm:ss');
        }
        if (result.refund_time) {
            result.refund_time = dayjs(result.refund_time).format('YYYY-MM-DD HH:mm:ss');
        }
        if (result.cancel_time) {
            result.cancel_time = dayjs(result.cancel_time).format('YYYY-MM-DD HH:mm:ss');
        }

        return result;
    }

    /**
     * 申请退款
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async refund(params) {
        const { ctx } = this;
        const { id, refund_reason } = params;
        const transaction = await ctx.model.transaction();

        try {
            // 查询订单
            const order = await this.ctx.model.Order.findOne({
                where: { id }
            });

            if (!order) {
                throw new Error('订单不存在');
            }

            // 判断订单状态
            if (order.status !== OrderStatusEnum.PAID) {
                throw new Error('订单状态不正确：' + order.status);
            }

            // 更新订单状态
            await order.update({
                status: OrderStatusEnum.REFUNDING,
                refund_time: new Date(),
                refund_reason,
            }, { transaction });

            await transaction.commit();
            return true;
        } catch (error) {
            await transaction.rollback();
            throw error;
        }
    }

    /**
     * 处理退款
     */
    async refundConfirm(data) {
        const { id, refund_remark, refund_amount } = data;

        // 查询订单
        const order = await this.ctx.model.Order.findOne({
            where: { id }
        });

        if (!order) {
            throw new Error('订单不存在');
        }
        let refund_amount_int = Number(refund_amount)
        if (!refund_amount_int) {
            // 不同意退款
            await order.update({
                status: OrderStatusEnum.PAID,
                refund_time: new Date(),
                refund_remark,
            });
            return true
        } else {
            // 同意退款
            if (refund_amount_int >= order.payment_amount) {
                refund_amount_int = order.payment_amount
            }
            try {
                await order.update({
                    status: OrderStatusEnum.REFUNDING,
                });
                // 掉用退款接口
                await this.ctx.service.orderRefund.processRefund({
                    order_no: order.order_no,
                    refund_remark,
                    refund_amount: refund_amount_int,
                    payment_amount: order.payment_amount
                })
            } catch (e) {
                throw e
            }
        }
    }

    /**
     * 删除订单
     * @param {Object} params - 参数
     * @return {Promise<boolean>}
     */
    async delete(params) {
        const { id } = params;

        // 查询订单
        const order = await this.model.findOne({
            where: { id }
        });

        if (!order) {
            throw new Error('订单不存在');
        }

        // 只有已取消、已退款的订单可以删除
        if (![OrderStatusEnum.CANCELLED].includes(order.status)) {
            throw new Error('只有已取消的订单才能删除');
        }

        // 软删除订单
        await this.ctx.model.Order.destroy({
            where: {
                id
            }
        })

        return true;
    }
}

module.exports = OrderService;
